package com.hk.web.core.intercept;

import com.hk.commons.utils.HmacUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.google.common.base.Strings.nullToEmpty;

public class AuthInterceptor extends HandlerInterceptorAdapter {

    private static Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);

    private String tokenKey = "Auth-Token";

    private String contentKey = "Auth-Content";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {



        String url = request.getRequestURL().toString();
        // 区分GET、DELETE和POST、PUT请求处理
        String method = request.getMethod();
        if ("GET".equals(method) || "DELETE".equals(method)) {
            String queryStr = nullToEmpty(request.getQueryString());
            if (StringUtils.isNotBlank(queryStr)) {
                queryStr = "?" + queryStr;
            }
            url = url + queryStr;
        } else if ("POST".equals(method) || "PUT".equals(method)) {
            url += getBodyString(request.getReader());
        } else {
            logger.error("[{}]请求不支持",method);
            return false;
        }

        // 客户端生成的Mac密钥
        String key = request.getHeader(tokenKey);
        // 客户端生成的消息摘要
        String content = request.getHeader(contentKey);
        if (StringUtils.isBlank(key) || StringUtils.isBlank(content) || key.length() != 44
                || content.length() != 64) {
            return false;
        }
        // 服务端鉴权
        Date nowDate = new Date();
        List<String> authList = new ArrayList<>(3);
        for (int i = -1; i <= 1; i++) {
            authList.add(HmacUtil.encryptHMAC(key, url, DateUtils.addMinutes(nowDate, i)));
        }
        if (authList.contains(content)) {
            return true;
        }
        logger.error("远程加密校验失败，拒绝访问！");
        return false;
    }

    private String getBodyString(BufferedReader br) {
        String inputLine;
        StringBuffer sb = new StringBuffer();
        try {
            while ((inputLine = br.readLine()) != null) {
                sb.append(inputLine);
            }
            br.close();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return sb.toString();
    }

}
